/// <reference path="../utilities/BigInteger.js" />
/// <reference path="../utilities/Color.js" />
/// <reference path="../utilities/FXDom.js" />
/// <reference path="../utilities/Xpcom.js" />
///--------------------------------------------------------------------
/// <file name="NAMFoxPreferences.js">
///   Logic for the NAMFox Preferences view.
/// </file>
///--------------------------------------------------------------------

with (NAMFox) {

var NAMFoxPreferences = {
    _messageChanges: {},
    _smileyData: null,
    
    backupCustomMessages: function() {
        /// <summary>
        ///   Backs up custom messages.
        /// </summary>
        
        $.messages.backup();
    },
    
    conformQuickReplyHeight: function(event) {
        /// <summary>
        ///   Conforms the user's entry for the quick reply height.
        /// </summary>
        /// <param name="event">
        ///   The event data.
        /// </param>
        
        var textBox = event.target;
        var value = parseInt(textBox.value);
        
        if (!value || value < 10) {
            textBox.value = "10";
        }
        else if (value > 30) {
            textBox.value = "30";
        }
        else {
            // We do this because parseInt("5asdf") == 5
            textBox.value = value.toString();
        }
    },
    
    conformQuickReplyWidth: function(event) {
        /// <summary>
        ///   Conforms the user's entry for the quick reply width.
        /// </summary>
        /// <param name="event">
        ///   The event data.
        /// </param>
        
        var textBox = event.target;
        var value = parseInt(textBox.value);
        
        if (!value || value < 30) {
            textBox.value = "30%";
        }
        else if (value > 95) {
            textBox.value = "95%";
        }
        else {
            textBox.value = value + "%";
        }
    },
    
    initialize: function() {
        /// <summary>
        /// Called to initialize the NAMFox namespace. Since the paneload event
        /// occurs before the window.load event, we need to force the NAMFox namespace
        /// to load on all paneload event handlers.
        /// </summary>
        
        NAMFox.init();
    },
    
    onAcceptChanges: function() {
        /// <summary>
        ///   Called when the user clicks the OK button for the preferences window,
        ///   if it exists. Otherwise, this is called via the onClosed function
        ///   when the user closes the window.
        /// </summary>
        
        for (var key in this._messageChanges) {
            if (this._messageChanges.hasOwnProperty(key)) {
                var change = this._messageChanges[key];
                if (key === "defaultMessage") {
                    $.messages.getDefaultMessage().text = change.text;
                }
                else {
                    var message = $.messages.getMessage(key);
                    message.name = change.name;
                    message.text = change.text;
                }
            }
        }
        
        $.messages.save();
        
        if (this._smileyData) {
            $.getConfig().toolbar.enabledSmileys = this._smileyData.toString();
        }

        var disableDoubleClickForVideo = $FX("#quick-edit-disable-double-click-for-media");
        if (disableDoubleClickForVideo.length) {
            if (disableDoubleClickForVideo.attr("checked")) {
                $.getConfig().quickEdit.disableDoubleClickForPostsWithMedia = 1;
            }
            else {
                $.getConfig().quickEdit.disableDoubleClickForPostsWithMedia = 0;
            }
        }
    },
    
    onClosed: function() {
        /// <summary>
        ///   Called when the preferences dialog is closed.
        /// </summary>
        
        if ($FX("#BrowserPreferences").attr("instantApply")) {
            this.onAcceptChanges();
        }
        
        return true;
    },
    
    onCustomMessageNameChange: function(event) {
        /// <summary>
        ///   Called when the selected custom message's name has changed.
        /// </summary>
        /// <param name="event">
        ///   Contains the event data.
        /// </param>
        
        var selectedItem = $FX("#message-menu").attr("selectedItem");
        
        if (selectedItem) {
            var selectedValue = selectedItem.value;
            
            var newName = event.target.value;
            if (!this._messageChanges[selectedValue]) {
                this._messageChanges[selectedValue] = {
                    key: selectedValue,
                    name: newName,
                    text: $FX("#message-text").val()
                };
                $.verbose("PREFS | Key: " + selectedValue + " | Name: " + newName + " | Text: " + this._messageChanges[selectedValue].text);
            }
            else {
                this._messageChanges[selectedValue].name = newName;
            }
            
            selectedItem.label = newName;
        }
    },
    
    onCustomMessageTextChange: function(event) {
        /// <summary>
        ///   Called when the selected custom message's name has changed.
        /// </summary>
        /// <param name="event">
        ///   Contains the event data.
        /// </param>
        
        var selectedItem = $FX("#message-menu").attr("selectedItem");
        
        if (selectedItem) {
            var selectedValue = selectedItem.value;
            
            var newText = event.target.value;
            if (!this._messageChanges[selectedValue]) {
                this._messageChanges[selectedValue] = {
                    key: selectedValue,
                    name: $FX("#message-name").val(),
                    text: newText
                };
                $.verbose("PREFS | Key: " + selectedValue + " | Name: " + this._messageChanges[selectedValue].name + " | Text: " + newText);
            }
            else {
                this._messageChanges[selectedValue].text = newText;
            }
        }
    },
    
    onLightnessChanged: function(value) {
        /// <summary>
        /// Ensures that the scale, text box, and color boxes sync.
        /// </summary>
        /// <param name="value" type="Number" integer="true">
        /// The percentage value to sync with the color boxes.
        /// </param>
        
        document.getElementById("broadcaster-strip-markup-color-lightness").setAttribute("lightness", value);
    },
    
    onTextBoxLightnessChanged: function(event) {
        /// <summary>
        /// Conforms the user's entry for color lightness percentage
        /// to something within the valid range of values.
        /// </summary>
        /// <param name="event">
        /// The event data.
        /// </param>
        
        var textBox = event.target;
        var value = parseInt(textBox.value);

        if (!value || value < 0) {
            textBox.value = "0";
        }
        else if (value > 100) {
            textBox.value = "100";
        }
        else {
            // We do this because parseInt("5asdf") == 5
            textBox.value = value.toString();
        }
        
        NAMFoxPreferences.onLightnessChanged(value);
    },
    
    onMainPaneLoaded: function() {
        /// <summary>
        ///   Called when the main prefpane has loaded.
        /// </summary>
        
        this.initialize();
        $.verbose("PREFS | Moderator Check: " + $.getCurrentUser().userName + " / " + $.getCurrentUser().isModerator);

        if ($.getConfig().quickEdit.disableDoubleClickForPostsWithMedia === 1) {
            $FX("#quick-edit-disable-double-click-for-media").attr("checked", true);
        }
    },
    
    onMarkupAndSmileysPaneLoaded: function() {
        /// <summary>
        ///   Called when the markup/smiley prefpane has loaded.
        /// </summary>
        
        this.initialize();
        
        try {
            var count = {};
            var customSmileyUrls = $.getCurrentUser().getCustomSmileyUrls(count);
            
            if (count.value) {
                for (var i = 0; i < 5; ++i) {
                    var smiley = $FX("#namfox-custom-smiley-" + (i + 1).toString());

                    if (i >= count.value) {
                        smiley.attr("className", "hidden");
                        continue;
                    }

                    smiley.attr("image", customSmileyUrls[i]);
                }
            }
            
            // Now check the appropriate smileys
            var check = this._smileyData = new BigInteger($.getConfig().toolbar.enabledSmileys);
            
            var smileyCount = 92;
            for (var i = 0; i < smileyCount; ++i) {
                var hexValue = BigInteger.fromMultipleOfTwo(i);
                var listItem = $FX("#namfox-smileys listitem[data-index=" + i + "]").get(0);

                if (listItem) {
                    if (check.bitwiseAnd(hexValue).notEquals(0)) {
                        listItem.checked = true;
                    }
                
                    listItem.addEventListener(
                        "command",
                        function(value) {
                            return function (event) {
                                NAMFoxPreferences.onSmileyCheckedChanged(event, value);
                            }
                        }(i),
                        false
                    );
                }
            }
        }
        catch (e) {
            $.error(e);
        }
    },
    
    onMessageMenuSelectedIndexChanged: function() {
        /// <summary>
        ///   Called when the custom message menu's selected index has changed.
        /// </summary>
        
        var selectedItem = $FX("#message-menu").attr("selectedItem");
        
        if (selectedItem) {
            var selectedValue = selectedItem.value;
            this.updateMessageUI(selectedValue);
        }
    },
    
    onMessagesPaneLoaded: function() {
        /// <summary>
        ///   Called when the custom messages prefpane has loaded.
        /// </summary>
        
        this.initialize();
        var messageList = $FX("#message-list").get(0);
        
        $.messages.enumerate(
            function(message) {
                var menuItem = document.createElement("menuitem");
                menuItem.setAttribute("label", message.name);
                menuItem.setAttribute("value", message.key);
                
                messageList.appendChild(menuItem);
            }
        );
        
        var defaultMessage = document.createElement("menuitem");
        defaultMessage.setAttribute("label", "Default Message");
        defaultMessage.setAttribute("value", "defaultMessage");
        
        messageList.appendChild(defaultMessage);
        
        // Refreshes the label on the first message.
        $FX("#message-menu").attr("selectedIndex", 0);
        this.updateMessageUI("1");
    },
    
    onNeoseekerPaneLoaded: function() {
        /// <summary>
        /// Called when the Neoseeker preferences pane has loaded.
        /// </summary>
        
        this.initialize();
        var stripOptions = $.getConfig().stripMarkup.stripOptions;
        $FX("#strip-colors").attr("checked", (stripOptions & StripOptions.Color) !== 0);
        $FX("#normalize-size-one").attr("checked", (stripOptions & StripOptions.SizeOne) !== 0);
        $FX("#normalize-sub").attr("checked", (stripOptions & StripOptions.Sub) !== 0);
        $FX("#normalize-sup").attr("checked", (stripOptions & StripOptions.Sup) !== 0);
        
        var that = this;
        this.toggleColorDetail();
        var lightness = $.getConfig().stripMarkup.colorLightness;
        $FX("#color-details hbox box").each(
            function() {
                that.updateBoxColor(this, lightness);
            }
        );
    },
    
    onSmileyCheckedChanged: function(event, i) {
        /// <summary>
        ///   Called when a smiley check box has its check box added or removed.
        /// </summary>
        /// <param name="event">
        ///   Contains event data.
        /// </param>
        /// <param name="i" type="Number" integer="true">
        ///   The index of the check box.
        /// </param>
        
        var listItem = event.target;
        
        if (listItem.checked) {
            this._smileyData = this._smileyData.bitwiseOr(BigInteger.fromMultipleOfTwo(i));
        }
        else {
            this._smileyData = this._smileyData.bitwiseAndNot(BigInteger.fromMultipleOfTwo(i));
        }
    },
    
    restoreCustomMessages: function() {
        /// <summary>
        ///   Restores custom messages.
        /// </summary>
        
        $.messages.restore();
    },
    
    toggleColorDetail: function() {
        /// <summary>
        /// Toggles the color detail section depending on the check state
        /// of the "strip colors" check box.
        /// </summary>
        /// <param name="stripColors" type="Boolean">
        /// The check box which controls whether color details matter.
        /// </param>
        
        var disabled = !$FX("#strip-colors").attr("checked");
        $FX("#color-details hbox *").each(
            function() {
                this.disabled = disabled;
            }
        );
    },
    
    updateBoxColor: function(box, lightness) {
        /// <summary>
        /// Updates the color of a box on the Neoseeker page to
        /// indicate the user's selected lightness.
        /// </summary>
        /// <param name="box" type="Box">
        /// The box to update.
        /// </param>
        /// <param name="lightness" type="number" optional="true">
        /// (Optional) The lightness percentage.
        /// </param>
        
        var hue = parseInt(box.getAttribute("hue"));
        var saturation = box.getAttribute("saturation") || 255;
        var lightnessPercentage = lightness || parseInt(box.getAttribute("lightness"));
        lightness = (lightnessPercentage / 100) * 255;
        
        saturation = parseInt(saturation);
        
        var color = Color.fromHsl(hue, saturation, lightness).toHex();
        
        box.setAttribute("style", "background-color: " + color);
        box.setAttribute("tooltiptext", color);
    },
    
    updateMarkupStrippingPreferences: function(event) {
        /// <summary>
        /// Updates the markup strip preferences based on a check box being checked or unchecked.
        /// </summary>
        /// <param name="event">
        /// The event object containing event data.
        /// </param>
        
        var checkBox = event.target;
        
        if (checkBox.checked) {
            $.getConfig().stripMarkup.stripOptions |= checkBox.getAttribute("stripValue");
        }
        else {
            $.getConfig().stripMarkup.stripOptions &= ~(checkBox.getAttribute("stripValue"));
        }
    },
    
    updateMessageUI: function(messageKey) {
        /// <summary>
        /// Updates the messages preference UI by showing a particular message.
        /// </summary>
        /// <param name="messageKey" type="String">
        /// The key of the custom message to display.
        /// </param>
        
        var isDefaultMessage = messageKey === "defaultMessage";
        $FX("#message-name").attr("disabled", isDefaultMessage);
        $FX("#message-name-label").attr("disabled", isDefaultMessage);
        
        var message = this._messageChanges[messageKey];
        
        if (!message) {
            if (isDefaultMessage) {
                message = $.messages.getDefaultMessage();
            }
            else {
                message = $.messages.getMessage(messageKey);
            }
        }
        
        if (message) {
            $FX("#message-name").val(isDefaultMessage ? "Default Message" : message.name);
            $FX("#message-text").val(message.text);
        }
        else {
            $FX("#message-name").val(selectedItem.label);
            $FX("#message-text").val("");
        }
    }
};

};